package com.cm386.final_project_timezonealert;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleAdapter.ViewBinder;
import android.widget.TextView;

import com.cm386.final_project_timezonealert.dao.DBService;
import com.cm386.final_project_timezonealert.model.City;
import com.cm386.final_project_timezonealert.model.ReferenceCity;
import com.cm386.final_project_timezonealert.model.TimePickerDialogFragment;
import com.cm386.final_project_timezonealert.model.TimeZoneService;
import com.cm386.final_project_timezonealert.model.UpdateWeatherTask;
import com.cm386.final_project_timezonealert.model.Weather;
import com.cm386.final_project_timezonealert.view.SelectedCityItem;

public class MainActivity extends SwipeListViewActivity {
	//Message Type of schedule
	public final static int SCHEDULE_UPDATE_SELECTED_CITY_MSG_TYPE = 1;
	public final static int SCHEDULE_COLON_FLASHING = 2;
	
	//Time picker dialog's id
	public final static int TIME_PICKER_DIALOG = 0;
	 
	public final static String SOURCE_HOUR_KEY    = "SOURCE_HOUR";
	public final static String SOURCE_MINIUTE_KEY = "SOURCE_MINUTE";
	
	//Timer for schecule update all selected city status.
	Timer scheduleUpdateSelectedCityTimer;
	//Timer for schecule flashing colon.
	Timer scheduleColonFlashing;
	
	//City that use to reference when convert different city time.
	ReferenceCity referenceCity;
	//Cities that user already to monitor list.
	List<City> selectedCities;
	ListView listView;
	Integer selectedItemPosition = null;
	//listView item data source
	List<SelectedCityItem> selectedCityItems;
	
	Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			if (msg.what == SCHEDULE_UPDATE_SELECTED_CITY_MSG_TYPE) {
				SimpleAdapter adapter = (SimpleAdapter) listView.getAdapter();
				updateListViewAdapterByCities(adapter, selectedCities);
				adapter.notifyDataSetChanged();
			}
			if (msg.what == SCHEDULE_COLON_FLASHING) {
				SimpleAdapter adapter = (SimpleAdapter) listView.getAdapter();
				updateColonFlashing(adapter);
				adapter.notifyDataSetChanged();
			}
			super.handleMessage(msg);
		}
	};
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		
		
		selectedCities    = DBService.getInstance(this).fetchAllCity();
		Log.v("Final Project", "The size of selectedCities : " + selectedCities.size());
		selectedCityItems = new ArrayList<SelectedCityItem>();
		
		Bitmap defaultWeathIcon = BitmapFactory.decodeResource(this.getResources(), R.drawable.loading);
		String defaultTemperature = "--º";
		for (City city : selectedCities){
			
			Weather weather = new Weather();
			weather.setWeatherIcon(defaultWeathIcon);
			weather.setTemperature(defaultTemperature);
			weather.setDayNightLabel(Weather.DEFAULT_DAY_NIGHT_LABEL);
			city.setWeather(weather);
			
			selectedCityItems.add(new SelectedCityItem(city.getName(), 
														TimeZoneService.toTimeZoneString(city.getTimeZone()), 
														TimeZoneService.toCurrentHourString(city.getTimeZone()),
														":",
														TimeZoneService.toCurrentMinutesString(city.getTimeZone()),
														city.getWeather().getWeatherIcon(),
														city.getWeather().getTemperature(),
														city.getWeather().getDayNightLabel()
														));
		}
		int[] selectedCityItemId     = new int[]{R.id.city_name, R.id.time_zone, R.id.hour, R.id.colon, R.id.minutes, R.id.weatherIcon, R.id.temperature, R.id.day_night_label};
		String[] selectedCityItemKey = new String[]{SelectedCityItem.CITY_NAME_KEY,
													SelectedCityItem.TIME_ZONE_KEY,
													SelectedCityItem.HOUR_KEY,
													SelectedCityItem.COLON_KEY,
													SelectedCityItem.MINUTES_KEY,
													SelectedCityItem.WEATHER_ICON_KEY,
													SelectedCityItem.TEMPERATURE_KEY,
													SelectedCityItem.DAY_NIGHT_LABEL_KEY};
		SimpleAdapter adapter = new SimpleAdapter(this, selectedCityItems, R.layout.selected_city_item, selectedCityItemKey, selectedCityItemId){
			public View getView (int position, View convertView, ViewGroup parent){
				View localView = super.getView(position, convertView, parent);
				if (selectedItemPosition!=null && selectedItemPosition==position && referenceCity!=null)
					//localView.setBackgroundColor(Color.parseColor("#ff00ddff"));
					localView.setBackgroundColor(Color.YELLOW);
				else
					localView.setBackgroundColor(Color.WHITE);					
				return localView;
			}
		};
		
		adapter.setViewBinder(new ViewBinder() {                
	           public boolean setViewValue(View view, Object data,  
	                   String textRepresentation) {  
	               if(view instanceof ImageView  && data instanceof Bitmap){  
	                   ImageView iv = (ImageView) view;  	                  
	                   iv.setImageBitmap((Bitmap) data);  
	                   return true;  
	               }
	               else if (view instanceof TextView  && data instanceof String) {
	            	   TextView tv = (TextView) view;
	            	   String d = (String) data;
	            	   if (d.equals(Weather.DAY_LABEL)) {
	            		   tv.setText(Weather.DAY_LABEL);
	            		   tv.setBackgroundColor(Color.LTGRAY);
	            		   tv.setTextColor(Color.LTGRAY);
	            	   } else if (d.equals(Weather.NIGHT_LABEL)) {
	            		   tv.setText(Weather.NIGHT_LABEL);
	               		   tv.setBackgroundColor(Color.DKGRAY);
	            		   tv.setTextColor(Color.DKGRAY);
	            	  
	               } else if (d.equals(Weather.DEFAULT_DAY_NIGHT_LABEL)) {
            		   tv.setText(Weather.DEFAULT_DAY_NIGHT_LABEL);
               		   tv.setBackgroundColor(Color.TRANSPARENT);
            		   tv.setTextColor(Color.TRANSPARENT);
            	   }else {
	            		   tv.setText(d);
	            	   }
	            	   return true;
	               }
	               else  
	               return false;  
	           }  
	    });
	      

		listView = (ListView) findViewById(R.id.selectedCityItemList);
		listView.setAdapter(adapter);
		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> adapter, View view, int position,
					long id) {
				selectedItemPosition = position;
				TextView hourTextView 	= (TextView) view.findViewById(R.id.hour);
				String hourText			= (String) hourTextView.getText();
				TextView minuteTextView	= (TextView) view.findViewById(R.id.minutes);
				String minuteText		= (String) minuteTextView.getText();
				FragmentManager fm 		= getFragmentManager();
				TimePickerDialogFragment timePickerDialogFragment = TimePickerDialogFragment.getInstance(Integer.parseInt(hourText), Integer.parseInt(minuteText), position, selectedCities.get(position));
				timePickerDialogFragment.show(fm, "City Time Picker");
			}
		});
		
		UpdateWeatherTask uwt = new UpdateWeatherTask();
		uwt.execute(listView.getAdapter(), selectedCities, defaultWeathIcon, defaultTemperature);
		//uwt.execute(listView.getAdapter(), selectedCities, selectedDateTime);
		
		setScheduleUpdateSelectedCity(60000);
		setScheduleColonFlashing(500);		
	}
	
	public void timePickerSetTimeCallBack(int sourceHour, int sourceMinute, int position){
		referenceCity	= new ReferenceCity(selectedCities.get(position).getName(),
											selectedCities.get(position).getTimeZoneId(),
											selectedCities.get(position).getTimeZone(),
											selectedCities.get(position).getBelongRegion(),
											selectedCities.get(position).getWeather(),
											position, 
											sourceHour,
											sourceMinute);
		invalidateOptionsMenu();
		
		Message msg = mHandler.obtainMessage();
        msg.what = SCHEDULE_UPDATE_SELECTED_CITY_MSG_TYPE;  
        msg.sendToTarget();  
		Log.v("Final Project", "TimePickerSetTimeCallBack called.");
	}
	
	public void setScheduleUpdateSelectedCity(int time){
		scheduleUpdateSelectedCityTimer = new Timer("Timer Service For Update Time");
		Log.v("Final Project", "Timer Service For Update Time - Time:" + time);
		scheduleUpdateSelectedCityTimer.scheduleAtFixedRate(new TimerTask(){
			private int time;
			
			public TimerTask init(int time){
				this.time = time;
				return this;
			}
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Message msg = mHandler.obtainMessage();  
                msg.what = SCHEDULE_UPDATE_SELECTED_CITY_MSG_TYPE;  
                msg.sendToTarget();  
				//Log.v("Final Project", "Timer Service For Update Time Active.");
			}}.init(time), 
		60000, time);		
	}
	
	public void setScheduleColonFlashing(int time){
		scheduleColonFlashing = new Timer("Timer Service For Colon Flashing");
		Log.v("Final Project", "Timer Service For Colon Flashing - Time:" + time);
		scheduleColonFlashing.scheduleAtFixedRate(new TimerTask(){
			private int time;
			
			public TimerTask init(int time){
				this.time = time;
				return this;
			}
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Message msg = mHandler.obtainMessage();  
                msg.what 	= SCHEDULE_COLON_FLASHING;  
                msg.sendToTarget();  
				//Log.v("Final Project", "Timer Service For Colon Flashing Active.");
			}}.init(time), 
		500, time);		
	}

	public void updateListViewAdapterByCities(SimpleAdapter adapter, List<City> selectedCities){			
		for (int i=0; i<selectedCities.size(); i++){
			City city = selectedCities.get(i);
			SelectedCityItem selectedCityItem = (SelectedCityItem)adapter.getItem(i);
			if (referenceCity == null){
				selectedCityItem.setHour(TimeZoneService.toCurrentHourString(city.getTimeZone()));
				selectedCityItem.setMinutes(TimeZoneService.toCurrentMinutesString(city.getTimeZone()));
				selectedCityItem.setWeatherIcon(city.getWeather().getWeatherIcon());
				selectedCityItem.setTemperature(city.getWeather().getTemperature());
			} else {
				selectedCityItem.setHour(TimeZoneService.toDestinationHourStringByReference(referenceCity.getReferenceHour(), referenceCity.getReferenceMinute(), referenceCity.getTimeZone(), city.getTimeZone()));
				selectedCityItem.setMinutes(TimeZoneService.toDestinationMinutesStringByReference(referenceCity.getReferenceHour(), referenceCity.getReferenceMinute(), referenceCity.getTimeZone(), city.getTimeZone()));
				selectedCityItem.setWeatherIcon(city.getWeather().getWeatherIcon());
				selectedCityItem.setTemperature(city.getWeather().getTemperature());
			}
		}
	}
	
	public void updateColonFlashing(SimpleAdapter adapter){
		for (int i=0; i<selectedCities.size(); i++){
			SelectedCityItem selectedCityItem = (SelectedCityItem)adapter.getItem(i);
			if (selectedCityItem.getColon().trim().equals(":"))
				selectedCityItem.setColon(" ");
			else 
				selectedCityItem.setColon(":");
		}
	}
	

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		menu.findItem(R.id.action_convert_to_current).setVisible(false);
		return super.onCreateOptionsMenu(menu);
	}
	
	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		if (referenceCity != null){
			menu.findItem(R.id.action_convert_to_current).setVisible(true);
		} else {
			menu.findItem(R.id.action_convert_to_current).setVisible(false);
		}
		return super.onPrepareOptionsMenu(menu);
	}
	
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		if (scheduleUpdateSelectedCityTimer != null)
			scheduleUpdateSelectedCityTimer.cancel();
		if (scheduleColonFlashing != null)
			scheduleColonFlashing.cancel();
		super.onDestroy();
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
			case R.id.action_add_city:
				Intent regionActivity = new Intent(this, RegionActivity.class);
				startActivity(regionActivity);
				return true;
			case R.id.action_convert_to_current:
				selectedItemPosition = null;
				referenceCity = null;
				invalidateOptionsMenu();
				Message msg = mHandler.obtainMessage();
		        msg.what = SCHEDULE_UPDATE_SELECTED_CITY_MSG_TYPE;  
		        msg.sendToTarget();  
				return true;
			case R.id.action_discard:
				SimpleAdapter adapter = (SimpleAdapter) listView.getAdapter();
				selectedCityItems.clear();
				DBService.getInstance(this).deleteAllSelectedCity();
				selectedCities.clear();
				adapter.notifyDataSetChanged();
				return true;
			default:
				return super.onOptionsItemSelected(item);
		}
	}

	@Override
	public ListView getListView() {
		// TODO Auto-generated method stub
		return listView;
	}

	@Override
	public void getSwipeItem(boolean isRight, int position) {
		// TODO Auto-generated method stub
		if (isRight){
			referenceCity = null;
			SimpleAdapter adapter = (SimpleAdapter) listView.getAdapter();
			selectedCityItems.remove(position);
			DBService.getInstance(this).deleteSelectedCity(selectedCities.get(position));
			selectedCities.remove(position);
			adapter.notifyDataSetChanged();
			
		}
	}
}
